﻿using Google.Protobuf.WellKnownTypes;

namespace Elio.Sessions;

public class TextToSpeechSession : BaseSession
{
    protected override string SessionName => base.SessionName = "TextToSpeech";

    private ITextToSpeech? _tts;
    private SpeechOptions? _speechOptions;
    private CancellationTokenSource? _cts;

    protected override async Task OnCreate(long sid = 0, long fid = 0, params Any[] argv)
    {
        await base.OnCreate(sid, fid, argv);

        _tts = TextToSpeech.Default;
        Locale? locale = (from l in await TextToSpeech.Default.GetLocalesAsync()
                          where l.Language == "zh-CN"
                          select l).FirstOrDefault();
        _speechOptions = new() { Locale = locale };
        //await SendCallback(argv[0].P2Interaction());
    }

    protected override async Task OnReceive(string name, long sessionId, long futureId, params Any[] argv)
    {
        switch (name)
        {
            case "speak":
                await Speak(argv);
                break;

            case "stop":
                Stop();
                break;

            case "setOnStartListener":
                SetOnStartListener();
                break;

            case "setOnStopListener":
                SetOnStopListener();
                break;

            case "setOnDoneListener":
                SetOnDoneListener();
                break;

            case "setOnErrorListener":
                SetOnErrorListener();
                break;

            default:
                await base.OnReceive(name, sessionId, futureId, argv);
                break;
        }
    }

    private async Task Speak(params Any[] argv)
    {
        using (_cts = new CancellationTokenSource())
        {
            await _tts!.SpeakAsync(argv[0].P2String(), _speechOptions, _cts.Token);
        }
    }

    private void Stop()
    {
        if (_cts is null || _cts.IsCancellationRequested) return;
        _cts?.Cancel();
    }

    private static void SetOnStartListener() { }
    private static void SetOnStopListener() { }
    private static void SetOnDoneListener() { }
    private static void SetOnErrorListener() { }
}